package cn.buglife.concurrent.semaphore;

import java.util.concurrent.Semaphore;

/**
 * Semaphore 类是一个计数信号量。
 * 
 * <p>
 * 这就意味着它具备两个主要方法：
 * <li>{@link Semaphore#acquire()}</li>
 * <li>{@link Semaphore#release()}</li>
 * </p>
 *
 * <P>
 * 计数信号量由一个指定数量的 "许可" 初始化。每调用一次 acquire()，一个许可会被调用线程取走。每调用一次
 * release()，一个许可会被返还给信号量。因此，在没有任何 release() 调用时，最多有 N 个线程能够通过 acquire() 方法，N
 * 是该信号量初始化时的许可的指定数量。这些许可只是一个简单的计数器。
 * </P>
 * 
 * 信号量主要有两种用途：
 * <li>保护一个重要(代码)部分防止一次超过 N 个线程进入。</li>
 * <li>在两个线程之间发送信号。</li>
 * 
 * @author zhangjun
 */
public class SemaphoreSample {

  public static void main(String[] args) {

    // 一个信号数限制了同时只有一个线程能够获取到信号进行执行，当首次获取到信号的线程将信号释放掉之后，其他线程方可获取到信号（许可）
    Semaphore semaphore = new Semaphore(1);

    Runnable acquire = () -> {
      try {
        semaphore.acquire();

        Thread.sleep(10000);

        semaphore.release();
        System.out.println("信号释放成功");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };

    Runnable release = () -> {
      try {
        System.out.println("等待获取信号");
        semaphore.acquire();

        System.out.println("获取到信号");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    };

    new Thread(acquire).start();
    new Thread(release).start();
  }
}
